package edu.calvin.djs32.cs214.interpreters.calculator;

import edu.calvin.cs214.hobbes2008.HobbesTIR;
import edu.calvin.cs214.hobbes2008.LambdaTIR;
import edu.calvin.cs214.hobbes2008.TupleTIR;
import edu.calvin.cs214.hobbes2008.environments.IEnvironment;

public class ApplicableLambda implements Applicable {
	
	public LambdaTIR myLambda;

	public ApplicableLambda(LambdaTIR lambda) {
		myLambda = lambda;
	}

	public HobbesTIR apply(ICalculator calc, HobbesTIR... TIRs) {
		IEnvironment<HobbesTIR> nestedEnvironment = calc.getVariables().create();
		nestedEnvironment.add(myLambda.getIdentifier(), new TupleTIR(TIRs));
		Calculator nestedCalculator = new Calculator(calc.getPrimitives(), nestedEnvironment);
		return myLambda.getBody().accept(nestedCalculator);
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final ApplicableLambda other = (ApplicableLambda) obj;
		if (myLambda == null) {
			if (other.myLambda != null)
				return false;
		} else if (!myLambda.equals(other.myLambda))
			return false;
		return true;
	}
	
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((myLambda == null) ? 0 : myLambda.hashCode());
		return result;
	}

}
